import orekit
from org.orekit.frames import FramesFactory
from org.orekit.propagation.analytical.tle import TLE, TLEPropagator
from org.orekit.time import TimeScalesFactory, AbsoluteDate
from org.orekit.utils import IERSConventions, Constants
from org.orekit.orbits import OrbitType, KeplerianOrbit
from sgp4.api import Satrec, WGS84, WGS72
from datetime import datetime, timedelta

from data.dataOrekit import getMonth


def tle_epoch_to_datetime(epoch_year, epoch_day):
    """
    将 TLE 中的 epoch year 和 epoch day 转换为标准 datetime 格式。

    :param epoch_year: TLE 中的年份，例如 24 表示 2024 年
    :param epoch_day: TLE 中的天数，格式为小数，表示该年的第几天
    :return: 对应的 datetime 对象 (UTC)
    """
    # 确定年份归属
    if epoch_year < 57:  # 根据 SGP4 规则，57 之前属于 2000 年之后
        year = 2000 + epoch_year
    else:
        year = 1900 + epoch_year

    # 转换天数为日期
    epoch_date = datetime(year, 1, 1) + timedelta(days=epoch_day - 1)
    return epoch_date


def calculate_tle_epoch_position_velocity(tle_line1, tle_line2):
    """
    根据 TLE 计算其 epoch 时间的卫星位置和速度。

    :param tle_line1: TLE 第一行
    :param tle_line2: TLE 第二行
    :return: (epoch_time, position, velocity)
             - epoch_time: TLE 的时间 (datetime)
             - position: 卫星位置 (km)，格式为 (x, y, z)
             - velocity: 卫星速度 (km/s)，格式为 (vx, vy, vz)
    """
    # 解析 TLE
    satellite = Satrec.twoline2rv(tle_line1, tle_line2, WGS84)

    # 提取 TLE 时间
    epoch_year = satellite.epochyr
    epoch_day = satellite.epochdays
    epoch_time = tle_epoch_to_datetime(epoch_year, epoch_day)

    # 将 epoch 转为儒略日
    jd, fr = satellite.jdsatepoch, satellite.jdsatepochF

    # 计算位置和速度
    e, r, v = satellite.sgp4(jd, fr)
    if e != 0:
        raise ValueError(f"SGP4 Propagation error, code: {e}")

    # 返回结果
    return epoch_time, r, v


def getPredictMsg_itrf(line1, line2, time_utc):
    tle = TLE(line1, line2)
    utc_time = datetime.strptime(time_utc, "%Y-%m-%d %H:%M:%S")
    # 创建 TLEPropagator
    propagator = TLEPropagator.selectExtrapolator(tle)

    # 设置目标时间（2024年1月1日0时0分2秒）
    utc = TimeScalesFactory.getUTC()
    month_enum = getMonth(utc_time.month)

    target_time = AbsoluteDate(
        utc_time.year, utc_time.month, utc_time.day,
        utc_time.hour, utc_time.minute,
        utc_time.second + utc_time.microsecond / 1e6,
        utc
    )

    # 传播到目标时间并获取轨道状态
    orbitProp = propagator.propagate(target_time)

    # 获取ITRF坐标系
    itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, False)

    # 获取ITRF坐标系中的PV坐标
    pv_coordinates_itrf = orbitProp.getPVCoordinates(itrf)

    kepler = KeplerianOrbit(orbitProp.getOrbit())


    # 获取位置、速度和加速度
    p_itrf = pv_coordinates_itrf.getPosition()
    v_itrf = pv_coordinates_itrf.getVelocity()
    a_itrf = pv_coordinates_itrf.getAcceleration()

    # 将 p_rsw 和 v_rsw 转换为列表
    p_itrf_list = [p_itrf.getX(), p_itrf.getY(), p_itrf.getZ()]
    v_itrf_list = [v_itrf.getX(), v_itrf.getY(), v_itrf.getZ()]
    a_itrf_list = [a_itrf.getX(), a_itrf.getY(), a_itrf.getZ()]

    # 提取六根数
    a = kepler.getA()  # 半长轴（m）
    e = kepler.getE()  # 偏心率
    i = kepler.getI()  # 轨道倾角（rad）
    raan = kepler.getRightAscensionOfAscendingNode()  # 升交点赤经（rad）
    omega = kepler.getPerigeeArgument()  # 近地点幅角（rad）
    mean_anomaly = kepler.getMeanAnomaly()  # 平近点角（rad）

    # 返回一个合并的列表
    return p_itrf_list, v_itrf_list, a_itrf_list,[a,e,i,raan,omega,mean_anomaly]

# 示例使用
if __name__ == "__main__":
    # 示例 TLE 数据
    # tle_line1 = "1 41335U 16011A   24001.48389511  .00000177  00000-0  91083-4 0  9991"
    # tle_line2 = "2 41335  98.6302  70.6795 0000859 109.8694 250.2579 14.26740438410058"
    tle_line1 = "1 27944U 03042F   23365.91886760  .00000101  00000-0  29022-4 0  9990"
    tle_line2 = "2 27944  98.2882 140.0552 0011603 327.1746  32.8733 14.63434870 81963"
    target_date = "2024-01-01 00:06:00"
    # try:
    #     epoch_time, position, velocity = calculate_tle_epoch_position_velocity(tle_line1, tle_line2)
    #     print(f"TLE 时间 (UTC): {epoch_time}")
    #     print(f"位置 (km): X={position[0]}, Y={position[1]}, Z={position[2]}")
    #     print(f"速度 (km/s): VX={velocity[0]}, VY={velocity[1]}, VZ={velocity[2]}")
    # except ValueError as e:
    #     print(f"计算失败: {e}")

    p_itrf, v_itrf, a_itrf,kepler_data = getPredictMsg_itrf(tle_line1, tle_line2, target_date)
    print(f"预测时间 (UTC): {target_date}")
    print(f"位置 (m): X={p_itrf[0]}, Y={p_itrf[1]}, Z={p_itrf[2]}")
    print(f"速度 (m/s): VX={v_itrf[0]}, VY={v_itrf[1]}, VZ={v_itrf[2]}")
    print(f"半长轴 (m): a={kepler_data[0]}")
    print(f"离心率 : e={kepler_data[1]}")
    print(f"轨道倾角 (rad): i={kepler_data[2]}")
    print(f"升交点赤经 (rad): raan={kepler_data[3]}")
    print(f"近地点辐角 (rad): omega={kepler_data[4]}")
    print(f"平近点角 (rad): mean_anomaly={kepler_data[5]}")
